package com.robot.member.service;

import com.alibaba.fastjson.JSON;
import com.robot.member.client.CouponClient;
import com.robot.member.client.GoodsClient;
import com.robot.member.client.MerchantClient;
import com.robot.member.client.OrdersClient;
import com.robot.member.dao.CartDao;
import com.robot.member.pojo.Address;
import com.robot.member.pojo.Cart;
import com.robot.member.pojo.CartDetails;
import com.robot.member.pojo.Member;
import com.robot.member.pojo.client.Goods;
import com.robot.member.pojo.client.Orders;
import com.robot.member.pojo.client.OrdersDetails;
import com.robot.member.pojo.client.Store;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import util.IdWorker;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * cart服务层
 *
 * @author wuyunbin
 */
@Service
public class CartService {
    @Autowired
    private CartDetailsService cartDetailsService;
    @Autowired
    private AddressService addressService;

    @Autowired
    private CartDao cartDao;

    @Autowired
    private MerchantClient merchantClient;
    @Autowired
    private GoodsClient goodsClient;
    @Autowired
    private OrdersClient ordersClient;
    @Autowired
    private CouponClient couponClient;

    @Autowired
    private IdWorker idWorker;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * store表status 状态 0-禁用 1-启用
     */
    private String storeStatusEnable = "1";
    /**
     * goods表的on_sale 上下架状态 0-下架 1-上架
     */
    private String goodsOnSaleFailed = "0";
    private String goodsOnSaleSuccess = "1";
    /**
     * goods表status 审核状态  0-待审核 1-审核通过 2-审核未通过
     */
    private String goodsStatus = "0";
    private String goodsStatusSuccess = "1";
    private String goodsStatusFailed = "2";


    /**
     * 查询全部列表
     *
     * @return
     */
    public List<Cart> findAll() {
        return cartDao.findAll();
    }


    /**
     * 条件查询+分页
     *
     * @param whereMap
     * @param page
     * @param size
     * @return
     */
    public Page<Cart> findSearch(Map whereMap, int page, int size) {
        Specification<Cart> specification = createSpecification(whereMap);
        PageRequest pageRequest = PageRequest.of(page - 1, size);
        return cartDao.findAll(specification, pageRequest);
    }


    /**
     * 条件查询
     *
     * @param whereMap
     * @return
     */
    public List<Cart> findSearch(Map whereMap) {
        Specification<Cart> specification = createSpecification(whereMap);
        return cartDao.findAll(specification);
    }

    /**
     * 根据ID查询实体
     *
     * @param id
     * @return
     */
    public Cart findById(String id) {
        return cartDao.findById(id).orElse(null);
    }

    /**
     * 增加
     *
     * @param cart
     */
    public void add(Cart cart) {
        cartDao.save(cart);
    }

    /**
     * 修改
     *
     * @param cart
     */
    public void update(Cart cart) {
        cartDao.save(cart);
    }

    /**
     * 删除
     *
     * @param id
     */
    public void deleteById(String id) {
        cartDao.deleteById(id);
    }

    /**
     * 动态条件构建
     *
     * @param searchMap
     * @return
     */
    private Specification<Cart> createSpecification(Map searchMap) {
        return new Specification<Cart>() {
            @Override
            public Predicate toPredicate(Root<Cart> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicateList = new ArrayList<Predicate>();
                // id
                String id = "id";
                if (searchMap.get(id) != null && !"".equals(searchMap.get(id))) {
                    predicateList.add(cb.like(root.get(id).as(String.class), "%" + (String) searchMap.get(id) + "%"));
                }
                // 店铺id
                String storeId = "storeId";
                if (searchMap.get(storeId) != null && !"".equals(searchMap.get(storeId))) {
                    predicateList.add(cb.like(root.get(storeId).as(String.class), "%" + (String) searchMap.get(storeId) + "%"));
                }
                // 店铺名字
                String storeName = "storeName";
                if (searchMap.get(storeName) != null && !"".equals(searchMap.get(storeName))) {
                    predicateList.add(cb.like(root.get(storeName).as(String.class), "%" + (String) searchMap.get(storeName) + "%"));
                }
                // 会员id
                String memberId = "memberId";
                if (searchMap.get(memberId) != null && !"".equals(searchMap.get(memberId))) {
                    predicateList.add(cb.like(root.get(memberId).as(String.class), "%" + (String) searchMap.get(memberId) + "%"));
                }
                // 折扣
                String rate = "rate";
                if (searchMap.get(rate) != null && !"".equals(searchMap.get(rate))) {
                    predicateList.add(cb.like(root.get(rate).as(String.class), "%" + (String) searchMap.get(rate) + "%"));
                }
                //剔除软删除数据
                String deletedAt = "deletedAt";
                predicateList.add(cb.equal(root.get(deletedAt), cb.nullLiteral(LocalDateTime.class)));

                return cb.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
    }

    /**
     * 通过storeId和memberId查找cart
     *
     * @param storeId
     * @param memberId
     * @return
     */
    public Cart findByStoreIdAndMemberIdAndDeletedAtIsNull(String storeId, String memberId) {
        return cartDao.findByStoreIdAndMemberIdAndDeletedAtIsNull(storeId, memberId);
    }

    /**
     * 通过memberId查找全部cart
     *
     * @param memberId
     * @return
     */
    public List<Cart> findAllByMemberIdAndDeletedAtIsNullOrderByCreatedAtDesc(String memberId) {
        return cartDao.findAllByMemberIdAndDeletedAtIsNullOrderByCreatedAtDesc(memberId);
    }

    /**
     * 通过memberId查找全部cart
     *
     * @param memberId
     * @return
     */
    public void deleteAllByMemberId(String memberId) {
        cartDao.deleteAllByMemberId(memberId);
    }

    /**
     * 检查店铺
     *
     * @param storeId
     * @return
     */
    public Store checkStore(String storeId) {
        logger.info("storeId=" + storeId);
        if (storeId == null || "".equals(storeId)) {
            return null;
        }
        Store storeInDb = JSON.parseObject(merchantClient.thirdFindStoreById(storeId), Store.class);
        logger.info("storeInDb=" + storeInDb);
        if (storeInDb == null || storeInDb.getDeletedAt() != null || !storeStatusEnable.equals(storeInDb.getStatus())) {
            return null;
        }
        return storeInDb;
    }

    /**
     * 检查收货地址
     *
     * @param addressId
     * @param memberId
     * @return
     */
    public String checkAddress(String addressId, String memberId) {
        if (addressId == null || "".equals(addressId)) {
            logger.info("addressId is null");
            return "收货地址必填";
        }
        Address addressInDb = addressService.findByIdAndMemberId(addressId, memberId);
        logger.info("addressInDb=" + addressInDb);
        if (addressInDb == null || "".equals(addressInDb)) {
            logger.info("addressInDb is null and fore-end's addressId is" + addressInDb);
            return "收货地址不存在";
        }
        return "";
    }

    /**
     * 检查商品是否存在
     *
     * @param goodsId
     * @param storeId
     * @return
     */
    public Goods checkGoods(String goodsId, String storeId) {
        logger.info("goodsId=" + goodsId + ", storeId=" + storeId);
        if (goodsId == null || "".equals(goodsId)) {
            return null;
        }
        Goods goodsInDb = JSON.parseObject(goodsClient.thirdFindGoodsByIdAndStoreId(goodsId, storeId), Goods.class);
        logger.info("goodsInDb=" + goodsInDb);
        if (goodsInDb == null || !goodsStatusSuccess.equals(goodsInDb.getStatus()) || !goodsOnSaleSuccess.equals(goodsInDb.getOnSale())) {
            return null;
        }
        return goodsInDb;
    }

    /**
     * 检查商品数量
     *
     * @param goodsSum
     * @param goodsInDb
     * @return
     */
    public String checkGoodsSum(Integer goodsSum, Goods goodsInDb) {
        logger.info("goodsSum=" + goodsSum);
        if (goodsSum == null || "".equals(goodsSum)) {
            return "商品数量必填";
        }
        if (goodsSum < 0) {
            return "商品名(" + goodsInDb.getName() + ")的数量必须大于0";
        }
        if (goodsSum > goodsInDb.getStock()) {
            return "商品名(" + goodsInDb.getName() + ")的数量大于店家库存";
        }
        return "";
    }

    /**
     * 检查购物车
     *
     * @param cartId
     * @return
     */
    public Cart checkCart(String cartId) {
        if (cartId == null || "".equals(cartId)) {
            logger.info("cartId is null");
            return null;
        }
        Cart cartInDb = findById(cartId);
        logger.info("cartInDb=" + cartInDb);
        if (cartInDb == null || "".equals(cartInDb)) {
            logger.info("cartInDb is null and fore-end's cartId is" + cartId);
            return null;
        }
        return cartInDb;
    }

    /**
     * 更新购物车
     *
     * @param storeInDb
     * @param memberId
     * @param now
     */
    public Cart updateCart(Store storeInDb, String memberId, LocalDateTime now) {
        Cart cartInDb = findByStoreIdAndMemberIdAndDeletedAtIsNull(storeInDb.getId(), memberId);
        logger.info("cartInDb=" + cartInDb);
        if (cartInDb == null) {
            //增加购物车
            cartInDb = new Cart();
            cartInDb.setId(idWorker.nextId() + "");
            cartInDb.setStoreId(storeInDb.getId());
            cartInDb.setStoreName(storeInDb.getStoreName());
            cartInDb.setMemberId(memberId);
            cartInDb.setRate(storeInDb.getRate());
            cartInDb.setPacking(storeInDb.getPacking());
            cartInDb.setFreight(storeInDb.getFreight());
            cartInDb.setCreatedAt(now);
            cartInDb.setUpdatedAt(now);
            add(cartInDb);
        } else {
            //修改购物车
            cartInDb.setStoreName(storeInDb.getStoreName());
            cartInDb.setRate(storeInDb.getRate());
            cartInDb.setPacking(storeInDb.getPacking());
            cartInDb.setFreight(storeInDb.getFreight());
            cartInDb.setUpdatedAt(now);
            update(cartInDb);
        }
        return cartInDb;
    }

    /**
     * 更新购物车详细
     *
     * @param goodsInDb
     * @param cartId
     * @param goodsId
     * @param goodsSum
     * @param now
     */
    public CartDetails updateCartDetails(Goods goodsInDb, String cartId, String goodsId, Integer goodsSum, LocalDateTime now) {
        CartDetails cartDetailsInDb = cartDetailsService.findByCartIdAndGoodsIdAndDeletedAtIsNull(cartId, goodsInDb.getId());
        logger.info("cartDetailsInDb=" + cartDetailsInDb);
        if (cartDetailsInDb == null) {
            //增加购物车详情
            cartDetailsInDb = new CartDetails();
            cartDetailsInDb.setId(idWorker.nextId() + "");
            cartDetailsInDb.setCartId(cartId);
            cartDetailsInDb.setGoodsId(goodsId);
            cartDetailsInDb.setGoodsImage(goodsInDb.getImages());
            cartDetailsInDb.setGoodsName(goodsInDb.getName());
            cartDetailsInDb.setGoodsSum(goodsSum);
            cartDetailsInDb.setGoodsPrice(goodsInDb.getPrice());
            cartDetailsInDb.setCreatedAt(now);
            cartDetailsInDb.setUpdatedAt(now);
            cartDetailsService.add(cartDetailsInDb);
        } else {
            //修改购物车详情
            cartDetailsInDb.setGoodsImage(goodsInDb.getImages());
            cartDetailsInDb.setGoodsName(goodsInDb.getName());
            cartDetailsInDb.setGoodsSum(goodsSum);
            cartDetailsInDb.setGoodsPrice(goodsInDb.getPrice());
            cartDetailsInDb.setUpdatedAt(now);
            cartDetailsService.update(cartDetailsInDb);
        }
        return cartDetailsInDb;
    }

    /**
     * 更新订单
     *
     * @param orders
     * @param memberInDb
     * @param ordersId
     * @param price
     * @param rate
     * @param payAmount
     * @param discountAmount
     * @param addressId
     * @param now
     */
    public Orders updateOrders(Orders orders, Member memberInDb, String ordersId, BigDecimal price, Double rate, BigDecimal payAmount, BigDecimal discountAmount, String addressId, LocalDateTime now) {
        orders.setId(ordersId);
        orders.setMemberId(memberInDb.getId());
        orders.setNickname(memberInDb.getNickname());
        orders.setMemberGrade(memberInDb.getIsPlus());
        orders.setPrice(price);
        orders.setRate(rate);
        orders.setPayAmount(payAmount);
        orders.setDiscountAmount(discountAmount);
        orders.setStatus("0");
        orders.setAddressId(addressId);
        orders.setCreatedAt(now);
        orders.setUpdatedAt(now);
        return orders;
    }

    /**
     * 更新子订单
     *
     * @param orders
     * @param subOrders
     * @param storeInDb
     * @param memberInDb
     * @param subOrdersId
     * @param price
     * @param rate
     * @param payAmount
     * @param discountAmount
     * @param addressId
     * @param now
     * @return
     */
//    public Orders updateSubOrders(Orders orders,  Store storeInDb, Member memberInDb, String subOrdersId, BigDecimal price, Double rate, BigDecimal payAmount, BigDecimal discountAmount, String addressId, LocalDateTime now) {
//        subOrders.setId(subOrdersId);
//        subOrders.setOrdersId(orders.getId());
//        subOrders.setAgentId(storeInDb.getAgentId());
//        subOrders.setCompanyId(storeInDb.getCompanyId());
//        subOrders.setStoreId(storeInDb.getId());
//        subOrders.setStoreName(storeInDb.getStoreName());
//        subOrders.setArea(storeInDb.getArea());
//        subOrders.setMemberId(memberInDb.getId());
//        subOrders.setNickname(memberInDb.getNickname());
//        subOrders.setPhone(memberInDb.getPhone());
//        subOrders.setMemberGrade(memberInDb.getIsPlus());
//        subOrders.setPrice(price);
//        subOrders.setRate(rate);
//        subOrders.setPayAmount(payAmount);
//        subOrders.setDiscountAmount(discountAmount);
//        subOrders.setStatus("0");
//        subOrders.setEvaluating("0");
//        subOrders.setAddressId(addressId);
//        subOrders.setCreatedAt(now);
//        subOrders.setUpdatedAt(now);
//        return subOrders;
//    }

    /**
     * 修改购物车详细
     *
     * @param addOrdersDetailsList
     * @param goodsInDb
     * @param ordersId
     * @param subOrdersId
     * @param goodsSum
     * @param payAmountTemp
     * @param now
     * @return
     */
    public ArrayList<OrdersDetails> updateOrdersDetails(ArrayList<OrdersDetails> addOrdersDetailsList, Goods goodsInDb, String ordersId, String subOrdersId, Integer goodsSum, BigDecimal payAmountTemp, LocalDateTime now) {
        OrdersDetails ordersDetails = new OrdersDetails();
        ordersDetails.setId(idWorker.nextId() + "");
        ordersDetails.setGoodsId(goodsInDb.getId());
        ordersDetails.setGoodsName(goodsInDb.getName());
        ordersDetails.setOrdersId(ordersId);
        ordersDetails.setSubOrdersId(subOrdersId);
        ordersDetails.setPrice(goodsInDb.getPrice());
        ordersDetails.setNum(goodsSum);
        ordersDetails.setPayAmount(payAmountTemp);
        ordersDetails.setImage(goodsInDb.getImages());
        ordersDetails.setCreatedAt(now);
        ordersDetails.setUpdatedAt(now);
        addOrdersDetailsList.add(ordersDetails);
        return addOrdersDetailsList;
    }
}
